package test.service;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * 调用处理器实现类(有木有感觉这里就是传说中的AOP啊)
 * 每次生成动态代理类对象时都需要指定一个实现了该接口的调用处理器对象
 * 
 * 疑惑解开：
 * 1.代理类默认继承Porxy类，因为Java中只支持单继承，所以JDK动态代理只能去实现接口。
 * 2.代理方法都会去调用InvocationHandler的invoke()方法，因此我们需要重写InvocationHandler的invoke()方法。
 * 3.调用invoke()方法时会传入代理实例本身，目标方法和目标方法参数。解释了invoke()方法的参数是怎样来的。
 */
public class InvocationHandlerImpl implements InvocationHandler {

	/**
	 * 这个就是我们要代理的真实对象
	 */
	private Object subject;

	/**
	 * 构造方法，给我们要代理的真实对象赋初值
	 *
	 * @param subject
	 */
	public InvocationHandlerImpl(Object subject) {
		this.subject = subject;
	}

	/**
	 * 该方法负责集中处理动态代理类上的所有方法调用。
	 * 调用处理器根据这三个参数进行预处理或分派到委托类实例上反射执行
	 *
	 * @param proxy
	 *            代理类实例
	 * @param method
	 *            被调用的方法对象
	 * @param args
	 *            调用参数
	 * @return
	 * @throws Throwable
	 */
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		//在代理真实对象前我们可以添加一些自己的操作
		System.out.println("在调用之前，我要干点啥呢？");

		System.out.println("Method:" + method);

		//当代理对象调用真实对象的方法时，其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用
		Object returnValue = method.invoke(subject, args);
		System.out.println("比较一下代理类和subject类是不是同一个:" + subject == proxy);//false
		//在代理真实对象后我们也可以添加一些自己的操作
		System.out.println("在调用之后，我要干点啥呢？");

		return returnValue;
	}

}
